package com.acme.bankapp.domain.bank;

import java.io.Serializable;
import java.util.HashSet;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Set;

import com.acme.bankapp.domain.bank.exceptions.ClientAlreadyExistsException;

public class Bank implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private Set<Client> clients = new HashSet<Client>();

	public interface ClientRegistrationListener {
		void onClientAdded(Client client);
	}

	transient private List<ClientRegistrationListener> clientRegistrationListeners = new ArrayList<ClientRegistrationListener>();

	public Bank() {
		super();
		this.addDefaultClientRegistrationListeners();
	}

	public Bank(final List<ClientRegistrationListener> listeners) {
		this.clientRegistrationListeners.addAll(listeners);
	}

	public Client findClient(final Client client) {
		for (Client cl: clients) {
			if (cl.equals(client)){
				return cl;
			}
		}
		return null;
	}
	public Client addClient(final Client client)
			throws ClientAlreadyExistsException {
		if (clients.contains(client)) {
			throw new ClientAlreadyExistsException();
		}
		clients.add(client);
		for (ClientRegistrationListener clRegListener : clientRegistrationListeners) {
			clRegListener.onClientAdded(client);
		}
		return client;
	}
	public Set<Client> getClients() {
		return Collections.unmodifiableSet(clients);
	}

	public List<Account> getAllAccounts() {
		List<Account> allAccounts = new ArrayList<Account>();

		for (Client cl : clients) {
			allAccounts.addAll(cl.getAccounts());
		}

		return allAccounts;
	}

	public void addClientRegistrationListener(
			ClientRegistrationListener listener) {
		clientRegistrationListeners.add(listener);
	}

	public void addDefaultClientRegistrationListeners() {
		if (this.clientRegistrationListeners == null) {
			this.clientRegistrationListeners = new ArrayList<ClientRegistrationListener>();
		}
		this.addClientRegistrationListener(new Bank.ClientRegistrationListener() {
			public void onClientAdded(Client client) {
				System.out.println("Client " + client.getClientSalutation()
						+ " added");
			}
		});
		
		this.addClientRegistrationListener(new Bank.ClientRegistrationListener() {
			public void onClientAdded(Client client) {
				System.out.println("Notification email about the new client "
						+ client.getClientSalutation() + " to be sent");
			}
		});
	}
}
